home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / mus / play / tracker_4_31.lzh / tracker / Amiga / server / timer.c < prev   
C/C++ Source or Header  |  1995-02-13  |  4KB  |  160 lines

  1. /* amiga/server/timer.c */
  2.  
  3. /* $Id: timer.c,v 1.5 1995/02/13 22:08:26 Espie Exp espie $
  4.  * $Log: timer.c,v $
  5.  * Revision 1.5  1995/02/13  22:08:26  Espie
  6.  * No boolean. Changed include path.
  7.  *
  8.  * Revision 1.4  1994/01/07  15:58:17  Espie
  9.  * Semantics of TIME_WAIT has changed:
  10.  * we now input delays and the server computes what's needed.
  11.  * Makes Pause feasible !
  12.  *
  13.  * Revision 1.3  1994/01/05  14:56:02  Espie
  14.  * *** empty log message ***
  15.  *
  16.  * Revision 1.2  1994/01/05  04:35:23  Espie
  17.  * Suppressed old debug messages.
  18.  *
  19.  * Revision 1.1  1994/01/04  15:45:37  Espie
  20.  * Initial revision
  21.  *
  22.  */
  23.  
  24. #include <exec/nodes.h>
  25. #include <exec/memory.h>
  26. #include <devices/timer.h>
  27. #include <proto/exec.h>
  28. #include <proto/timer.h>
  29.  
  30. #ifdef EXTERNAL
  31. #include <stdio.h>
  32. #endif
  33.  
  34. #include "defs.h"
  35. #include "amiga/amiga.h"
  36. #include "amiga/server/server.h"
  37.  
  38. ID("$Id: timer.c,v 1.5 1995/02/13 22:08:26 Espie Exp espie $")
  39. LOCAL struct MsgPort *tport = 0;
  40. LOCAL struct timerequest *tr = 0;
  41. LOCAL int timer_opened = FALSE;
  42. LOCAL struct Library *TimerBase = 0;
  43.  
  44. /* the reference time at which the sound should play */
  45. LOCAL struct EClockVal play_time;
  46.  
  47.  
  48. /* auto adjusting facilities */
  49.  
  50. /* quantum = EClockFreq >> FRACTION
  51.  * Initially, time_lag = quantum << INITIAL
  52.  */
  53. #define FRACTION 7
  54. #define INITIAL 3
  55. /* the time lag between the current time and the time at which
  56.  * we want to play
  57.  */
  58. LOCAL ULONG time_lag;
  59. /* value to adjust it by each time we miss */
  60. LOCAL ULONG quantum;
  61.  
  62. /* check the time it is: have we got enough time left ? */
  63. LOCAL void check_time()
  64.    {
  65.    struct EClockVal current_time;
  66.    struct ext_message *msg;
  67.    unsigned long freq;
  68.  
  69.    freq = ReadEClock(¤t_time);
  70.    
  71.       /* compare time_play against current_time */
  72.    if (play_time.ev_hi < current_time.ev_hi ||
  73.       (play_time.ev_hi == current_time.ev_hi && play_time.ev_lo < current_time.ev_lo) )
  74.       {
  75.          /* we've fallen behind -> adjust play_time */
  76.       play_time.ev_hi = current_time.ev_hi;      
  77.       play_time.ev_lo = current_time.ev_lo + time_lag;
  78.       if (play_time.ev_lo < time_lag)
  79.          play_time.ev_hi++;
  80.          /* adjust delay */
  81.       time_lag += quantum;
  82.       }
  83.    }
  84.  
  85. struct MsgPort *open_timer()
  86.    {
  87.    int fail;
  88.  
  89.    tport = CreateMsgPort();
  90.    if (!tport)
  91.       return 0;
  92.    tr = CreateIORequest(tport, sizeof(struct timerequest));
  93.    if (!tr)
  94.       return 0;
  95.    fail = OpenDevice(TIMERNAME, UNIT_WAITECLOCK, (struct IORequest *)tr, 0);
  96.    if (fail)
  97.       return 0;
  98.    else
  99.       {
  100.       timer_opened = TRUE;
  101.       TimerBase = (struct Library *)tr->tr_node.io_Device;
  102.       return tport;
  103.       }
  104.    }
  105.  
  106. void close_timer(void)
  107.    {
  108.    if (timer_opened)
  109.       {
  110.       if (!CheckIO((struct IORequest *)tr))
  111.          {
  112.          AbortIO((struct IORequest *)tr);
  113.          WaitIO((struct IORequest *)tr);
  114.          }
  115.       CloseDevice((struct IORequest *)tr);
  116.       }
  117.    if (tr)
  118.       DeleteIORequest(tr);
  119.    if (tport)
  120.       DeleteMsgPort(tport);
  121.    }
  122.    
  123. void handle_timer(struct List *events, int signaled)
  124.    {
  125.    LOCAL int not_waiting = TRUE;
  126.    struct ext_message *msg;
  127.  
  128.    if (signaled)
  129.       {
  130.       while(GetMsg(tport))
  131.          {
  132.          do_events(events);
  133.          not_waiting = TRUE;
  134.          }
  135.       }
  136.  
  137.          /* if there is no timer request pending and some messages waiting, 
  138.           * we post one ! */
  139.    if (not_waiting && (msg = RemHead(events)))
  140.       {        /* if there is a time request, we use it */
  141.       if (msg->type == TYPE_WAIT)   
  142.          {
  143.          play_time.ev_lo += msg->data.time.low;
  144.          if (play_time.ev_lo < msg->data.time.low)
  145.             play_time.ev_hi++;
  146.          play_time.ev_hi += msg->data.time.high;
  147.          ReplyMsg(msg);
  148.          }
  149.       else     /* else we fake one (delay 0) */
  150.          AddHead(events, msg);
  151.       check_time();
  152.       tr->tr_node.io_Command = TR_ADDREQUEST;
  153.       tr->tr_time.tv_secs = play_time.ev_hi;
  154.       tr->tr_time.tv_micro = play_time.ev_lo;
  155.       SendIO((struct IORequest *)tr);
  156.       not_waiting = FALSE;
  157.       }
  158.    }   
  159.  
  160.